<?php

include_once('data.php');
include_once(Utils::getPath(array('model', 'user.php')));

class UserRepository {

    private $lastFilter;

    public function getById($userId) {
        if (is_numeric($userId)) {
            $row = Database::select('*', 'users', array(array('Id = ?', $userId, PDO::PARAM_INT)));

            if ($row->rowCount() == 1) {
                $user = $row->fetchObject('User');
                return $user;
            }
        }
        return null;
    }

    public function getAll($order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        return $this->find(null, $order, $desc, $pageIndex, $pageCount);
    }

    public function findByUserName($userName, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("UserName = ?", $userName, PDO::PARAM_STR);

        $res = $this->find($filterParams, $order, $desc, $pageIndex, $pageCount);

        if (count($res) != 1)
            return null;
        else
            return $res[0];
    }

    public function findByName($userName, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("Name LIKE ?", '%' . $userName . '%', PDO::PARAM_STR);

        return $this->find($filterParams, $order, $desc, $pageIndex, $pageCount);
    }

    public function find($filterParams, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        if (count($filterParams) > 0)
            $filterParams[] = array("AND IsDeleted = ?", (int) false, PDO::PARAM_BOOL);
        else
            $filterParams[] = array("IsDeleted = ?", (int) false, PDO::PARAM_BOOL);
        $rows = Database::select('*', 'users', $filterParams, $order, $desc, $pageIndex * $pageCount, $pageCount);
        $this->lastFilter = $filterParams;

        if ($rows) {
            $users = $rows->fetchAll(PDO::FETCH_CLASS, "User");
            return $users;
        }
        return null;
    }

    public function countLast() {
        $rows = Database::select('Count(*)', 'users', $this->lastFilter, null, null, null, null);

        if ($rows->rowCount() == 1) {
            $row = $rows->fetch(PDO::FETCH_NUM);
            return $row[0];
        }
        return null;
    }

    private function getLast() {
        $row = Database::select('*', 'users', null, 'Id', true, 0, 1);

        if ($row->rowCount() == 1) {
            $user = $row->fetchObject('User');
            return $user;
        }
        return null;
    }

    public function persist($user) {
        $values = array();

        $values[] = array('Name', $user->getName(), PDO::PARAM_STR);
        $values[] = array('UserName', $user->getUserName(), PDO::PARAM_STR);
        $values[] = array('Password', $user->getPassword(), PDO::PARAM_STR);
        $values[] = array('Email', $user->getEmail(), PDO::PARAM_STR);
        $values[] = array('IsDeleted', (int) $user->getIsDeleted(), PDO::PARAM_BOOL);
        if ($user->imageIsEmpty())
            $values[] = array('Image', '', PDO::PARAM_STR);
        else
            $values[] = array('Image', $user->getImage(false), PDO::PARAM_STR);
        $values[] = array('Description', $user->getDescription(), PDO::PARAM_STR);

        if (!$user->IsPersited()) {
            $res = Database::insert('users', $values);
            if ($res)
                return $this->getLast();
        }
        else {
            $res = DataBase::update('users', $values, array(array('Id = ?', $user->getId(), PDO::PARAM_INT)));
            if ($res)
                return $this->getById($user->getId());
        }

        return null;
    }

    public function remove($user) {
        $user->setIsDeleted($true);
        $this->persist($user);
    }
    
    public function removeReal($user) {
        $res = Database::remove('users', array(array('Id = ?', $user->getId(), PDO::PARAM_INT)));
        return $res;
    }

    public function getFriendsIds($userId, $acceted = null, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("(IdUser1 = ?", $userId, PDO::PARAM_INT);
        $filterParams[] = array("OR IdUser2 = ?)", $userId, PDO::PARAM_INT);
        if (!is_null($acceted)) {
            $filterParams[] = array("AND Accepted = ?", (int) $acceted, PDO::PARAM_BOOL);
        }
        $rows = Database::select('*', 'friends', $filterParams, null, null, $pageIndex * $pageCount, $pageCount);

        if ($rows) {
            $friendsIds = array();
            foreach ($rows as $row) {
                if ($row[0] == $userId)
                    $friendsIds[] = $row[1];
                else
                    $friendsIds[] = $row[0];
            }
            return $friendsIds;
        }
        return null;
    }

    public function getFriends($userId, $acceted = null, $pageIndex = 0, $pageCount = 10) {
        $friendsIds = $this->getFriendsIds($userId, $acceted, $pageIndex, $pageCount);

        if ($friendsIds != null && count($friendsIds) > 0) {
            $friendsIdsStr = '';
            for ($i = 0; $i < count($friendsIds) - 1; $i++) {
                $friendsIdsStr = $friendsIdsStr . $friendsIds[$i] . ',';
            }
            $friendsIdsStr = $friendsIdsStr . $friendsIds[count($friendsIds) - 1];

            $friendsList = $this->find(array(array('Id IN (' . $friendsIdsStr . ')')), null, null, 0, 0);
            return $friendsList;
        } else if ($friendsIds == null)
            return null;
        else
            return array();
    }

    public function getRequests($userId, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("IdUser2 = ?", $userId, PDO::PARAM_INT);
        $filterParams[] = array("AND Accepted = ?", (int) false, PDO::PARAM_BOOL);

        $rows = Database::select('IdUser1', 'friends', $filterParams, null, null, $pageIndex * $pageCount, $pageCount);
        if (($count = $rows->rowCount()) > 0) {
            $friendsIdsStr = '';
            $i = 0;
            foreach ($rows as $value) {
                $friendsIdsStr .= $value[0];
                if ($i < $count - 1)
                    $friendsIdsStr .= ',';
                $i++;
            }

            $friendsList = $this->find(array(array('Id IN (' . $friendsIdsStr . ')')), null, null, 0, 0);
            return $friendsList;
        }
        else if ($rows == null)
            return null;
        else
            return array();
    }

    public function countRequests($userId) {
        $filterParams = array();
        $filterParams[] = array("IdUser2 = ?", $userId, PDO::PARAM_INT);
        $filterParams[] = array("AND Accepted = ?", (int) false, PDO::PARAM_BOOL);

        $rows = Database::select('Count(*)', 'friends', $filterParams, null, null, 0, 0);
        if ($rows->rowCount() == 1) {
            $row = $rows->fetch(PDO::FETCH_NUM);
            return $row[0];
        }
        return null;
    }

    public function countFriends($userId, $acceted = null) {
        $filterParams = array();
        $filterParams[] = array("(IdUser1 = ?", $userId, PDO::PARAM_INT);
        $filterParams[] = array("OR IdUser2 = ?)", $userId, PDO::PARAM_INT);
        if (!is_null($acceted)) {
            $filterParams[] = array("AND Accepted = ?", (int) $acceted, PDO::PARAM_BOOL);
        }
        $rows = Database::select('Count(*)', 'friends', $filterParams, null, null, 0, 0);

        if ($rows->rowCount() == 1) {
            $row = $rows->fetch(PDO::FETCH_NUM);
            return $row[0];
        }
        return null;
    }

    public function setFriends($userId, $friendId, $accepted) {
        $filterParams = array();
        $filterParams[] = array("(IdUser1 = ?", $userId, PDO::PARAM_INT);
        $filterParams[] = array("AND IdUser2 = ?)", $friendId, PDO::PARAM_INT);
        $filterParams[] = array("OR (IdUser1 = ?", $friendId, PDO::PARAM_INT);
        $filterParams[] = array("AND IdUser2 = ?)", $userId, PDO::PARAM_INT);

        $rows = Database::select('*', 'friends', $filterParams, null, null, 0, 1);

        if ($rows->rowCount() == 1)
            return DataBase::update('friends', array(array('Accepted', (int) $accepted, PDO::PARAM_BOOL)), $filterParams);

        $values = array();
        $values[] = array('IdUser1', $userId, PDO::PARAM_INT);
        $values[] = array('IdUser2', $friendId, PDO::PARAM_INT);
        $values[] = array('Date', date("Y-m-d H:m:s"), PDO::PARAM_STR);
        $values[] = array('Accepted', (int) $accepted, PDO::PARAM_BOOL);

        return Database::insert('friends', $values);
    }

    public function getFriendsState($userId, $friendId) {
        $filterParams = array();
        $filterParams[] = array("(IdUser1 = ?", $userId, PDO::PARAM_INT);
        $filterParams[] = array("AND IdUser2 = ?)", $friendId, PDO::PARAM_INT);
        $filterParams[] = array("OR (IdUser1 = ?", $friendId, PDO::PARAM_INT);
        $filterParams[] = array("AND IdUser2 = ?)", $userId, PDO::PARAM_INT);

        $rows = Database::select('IdUser1, Accepted', 'friends', $filterParams, null, null, 0, 1);

        if ($rows->rowCount() == 1) {
            $row = $rows->fetch(PDO::FETCH_NUM);
            return array($row[1], $row[0] == $friendId);
        }

        return null;
    }

    public function removeFriends($userId, $friendId) {
        $filterParams = array();
        $filterParams[] = array("(IdUser1 = ?", $userId, PDO::PARAM_INT);
        $filterParams[] = array("AND IdUser2 = ?)", $friendId, PDO::PARAM_INT);
        $filterParams[] = array("OR (IdUser1 = ?", $friendId, PDO::PARAM_INT);
        $filterParams[] = array("AND IdUser2 = ?)", $userId, PDO::PARAM_INT);

        return Database::remove('friends', $filterParams);
    }

}

?>